﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;

namespace ReactiveCode.Observables
{
    using Util;

    static class Subject
    {
        class AnonymousSubject<T>: ISubject<T>
        {
            internal IObservable<T> _observable;
            internal IObserver<T> _observer;

            #region IObservable<T> Members

            public IDisposable Subscribe(IObserver<T> observer)
            {
                return _observable.Subscribe(observer);
            }

            #endregion

            #region IObserver<T> Members

            public void OnCompleted()
            {
                _observer.OnCompleted();
            }

            public void OnError(Exception error)
            {
                _observer.OnError(error);
            }

            public void OnNext(T value)
            {
                _observer.OnNext(value);
            }

            #endregion
        }
        public static ISubject<T> Create<T>(IObservable<T> observable, IObserver<T> observer)
        {
            Contract.Requires<ArgumentNullException>(observable != null, "observable");
            Contract.Requires<ArgumentNullException>(observer != null, "observer");
            return new AnonymousSubject<T> { _observable = observable, _observer = observer };
        }
        public static ISubject<T> Create<T>(IObservable<T> observable, Action<T> onNext)
        {
            Contract.Requires<ArgumentNullException>(observable != null, "observable");
            Contract.Requires<ArgumentNullException>(onNext != null, "onNext");
            Contract.Ensures(Contract.Result<ISubject<T>>() != null);
            return Create(observable, Observer.Create(onNext));
        }
    }
}
